package jp.co.nes.awssupport.control.function;

import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.s3.model.S3Object;

import jp.co.nes.awssupport.business.bean.CommonContainerBean.ProcessingResult;
import jp.co.nes.awssupport.common.base.AbstractRequestHandler;
import jp.co.nes.awssupport.common.base.CommonException;
import jp.co.nes.awssupport.common.utility.AppInfoUtil;
import jp.co.nes.awssupport.common.utility.AwsS3Helper;
import jp.co.nes.awssupport.common.utility.PropertiesUtil;

/**
 * アプリケーション情報作成です(Lambda)。<br>
 * DynamoDBに保存されているアプリケーション情報を全部削除し、s3に配置されているアプリケーション情報をDynamoDBに保存します。<br>
 * なお、本処理内では、アプリケーション情報のリロード、取得に関する処理は実施しないようにする必要があります(DynamoDBへの保存のみを実施します)。<br>
 * また、本処理を同時に複数実行しない前提になっているので、複数同時実行は実施しないで下さい。
 */
public class ApplicationInfoCreator extends AbstractRequestHandler<String, String> {

    /** ロガー */
    private static Logger logger = LoggerFactory.getLogger(ApplicationInfoCreator.class);

    /**
     * デフォルトコンストラクタです。
     */
    public ApplicationInfoCreator() {
    }

    /*
     * (非 Javadoc)
     * @see jp.co.nes.awssupport.common.base.AbstractRequestHandler#handleRequest(java.lang.Object, com.amazonaws.services.lambda.runtime.Context)
     */
    @Override
    public String handleRequest(String input, Context context) {
        // アプリケーション情報のリロード、取得に関する処理は実施しないようにする。
        // -> 本クラスの処理で、アプリケーション情報テーブルを作成する場合もあり、
        //    その場合、アプリケーション情報のリロード、取得を実施すると、エラーになるため、
        //    本クラスでは、アプリケーション情報のリロード、取得に関する処理は実施しないことになっている。
        AppInfoUtil.setReloadPossible(false);
        return super.handleRequest(input, context);
    }

    /*
     * (非 Javadoc)
     * @see jp.co.nes.awssupport.common.base.AbstractRequestHandler#handleRequest(java.lang.Object)
     */
    @Override
    protected String handleRequest(String input) {
        String bucketName = PropertiesUtil.getProperty("AppInfoBucketName", "awssupport-appinfo");
        String objectKey = PropertiesUtil.getProperty("AppInfoObjectKey", "AppInfo.yaml.gz");
        long rc = Long.parseLong(PropertiesUtil.getProperty("AppInfoReadCapacity", "10"));
        long wc = Long.parseLong(PropertiesUtil.getProperty("AppInfoWriteCapacity", "10"));

        if (logger.isDebugEnabled()) {
            logger.debug("BucketName=" + bucketName);
            logger.debug("ObjectKey=" + objectKey);
            logger.debug("CreateTableReadCapacity=" + rc);
            logger.debug("CreateTableWriteCapacity=" + wc);
        }

        try (InputStream inputStream = getYamlInputStream(bucketName, objectKey)) {
            AppInfoUtil.saveDynamoDb(inputStream, rc, wc);
        } catch (IOException e) {
            throw new CommonException(e);
        }
        return ProcessingResult.SUCCESS.name();
    }

    /**
     * s3に配置されているアプリケーション情報を読み込む入力ストリームを返却します。
     *
     * @param bucketName バケット名
     * @param objectKey オブジェクトキー
     * @return 入力ストリーム
     * @throws IOException IO例外
     */
    private InputStream getYamlInputStream(String bucketName, String objectKey) throws IOException {
        AwsS3Helper helper = createAwsS3Helper();
        S3Object s3Object = helper.getObject(bucketName, objectKey);

        InputStream inputStream = null;
        if (objectKey.endsWith(".gz")) {
            inputStream = new GZIPInputStream(s3Object.getObjectContent());
        } else {
            inputStream = s3Object.getObjectContent();
        }
        return inputStream;
    }

    /**
     * s3ヘルパーを生成します。
     *
     * @return s3ヘルパー
     */
    protected AwsS3Helper createAwsS3Helper() {
        return new AwsS3Helper();
    }
}
